// $ANTLR 3.4 src/main/resources/ModelDef.g 2012-02-18 23:27:47
package samples;

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

@SuppressWarnings({"all", "warnings", "unchecked"})
public class ModelDef extends TreeFilter {
    public static final String[] tokenNames = new String[] {
        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "CLSS_DECL", "COMMENT", "FIELD_DECL", "IDENTIFIER", "IDXF_DECL", "INDX_DECL", "ITFA_DECL", "LINE_COMMENT", "MEMBERS", "METHOD_DECL", "MODF_DECL", "REL_DECL", "TYPE_DECL", "UNIT", "WS", "'\"'", "'('", "')'", "','", "'.'", "';'", "'='", "'[]'", "'abstract'", "'class'", "'extends'", "'implements'", "'import'", "'interface'", "'null'", "'package'", "'public'", "'static'", "'{'", "'}'"
    };

    public static final int EOF=-1;
    public static final int T__19=19;
    public static final int T__20=20;
    public static final int T__21=21;
    public static final int T__22=22;
    public static final int T__23=23;
    public static final int T__24=24;
    public static final int T__25=25;
    public static final int T__26=26;
    public static final int T__27=27;
    public static final int T__28=28;
    public static final int T__29=29;
    public static final int T__30=30;
    public static final int T__31=31;
    public static final int T__32=32;
    public static final int T__33=33;
    public static final int T__34=34;
    public static final int T__35=35;
    public static final int T__36=36;
    public static final int T__37=37;
    public static final int T__38=38;
    public static final int CLSS_DECL=4;
    public static final int COMMENT=5;
    public static final int FIELD_DECL=6;
    public static final int IDENTIFIER=7;
    public static final int IDXF_DECL=8;
    public static final int INDX_DECL=9;
    public static final int ITFA_DECL=10;
    public static final int LINE_COMMENT=11;
    public static final int MEMBERS=12;
    public static final int METHOD_DECL=13;
    public static final int MODF_DECL=14;
    public static final int REL_DECL=15;
    public static final int TYPE_DECL=16;
    public static final int UNIT=17;
    public static final int WS=18;

    // delegates
    public TreeFilter[] getDelegates() {
        return new TreeFilter[] {};
    }

    // delegators


    public ModelDef(TreeNodeStream input) {
        this(input, new RecognizerSharedState());
    }
    public ModelDef(TreeNodeStream input, RecognizerSharedState state) {
        super(input, state);
    }

    public String[] getTokenNames() { return ModelDef.tokenNames; }
    public String getGrammarFileName() { return "src/main/resources/ModelDef.g"; }


        SymbolTable symtab;
        Scope currentScope;
        public ModelDef(TreeNodeStream input, SymbolTable symtab) {
            this(input);
            this.symtab = symtab;
            currentScope = symtab.globals;
        }



    // $ANTLR start "topdown"
    // src/main/resources/ModelDef.g:19:1: topdown : ( enterClass | enterInterface | fieldDeclaration | methodDeclaration );
    public final void topdown() throws RecognitionException {
        try {
            // src/main/resources/ModelDef.g:20:5: ( enterClass | enterInterface | fieldDeclaration | methodDeclaration )
            int alt1=4;
            switch ( input.LA(1) ) {
            case 28:
                {
                alt1=1;
                }
                break;
            case 32:
                {
                alt1=2;
                }
                break;
            case FIELD_DECL:
                {
                alt1=3;
                }
                break;
            case METHOD_DECL:
                {
                alt1=4;
                }
                break;
            default:
                if (state.backtracking>0) {state.failed=true; return ;}
                NoViableAltException nvae =
                    new NoViableAltException("", 1, 0, input);

                throw nvae;

            }

            switch (alt1) {
                case 1 :
                    // src/main/resources/ModelDef.g:20:9: enterClass
                    {
                    pushFollow(FOLLOW_enterClass_in_topdown60);
                    enterClass();

                    state._fsp--;
                    if (state.failed) return ;

                    }
                    break;
                case 2 :
                    // src/main/resources/ModelDef.g:21:7: enterInterface
                    {
                    pushFollow(FOLLOW_enterInterface_in_topdown68);
                    enterInterface();

                    state._fsp--;
                    if (state.failed) return ;

                    }
                    break;
                case 3 :
                    // src/main/resources/ModelDef.g:22:9: fieldDeclaration
                    {
                    pushFollow(FOLLOW_fieldDeclaration_in_topdown78);
                    fieldDeclaration();

                    state._fsp--;
                    if (state.failed) return ;

                    }
                    break;
                case 4 :
                    // src/main/resources/ModelDef.g:23:9: methodDeclaration
                    {
                    pushFollow(FOLLOW_methodDeclaration_in_topdown88);
                    methodDeclaration();

                    state._fsp--;
                    if (state.failed) return ;

                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "topdown"



    // $ANTLR start "bottomup"
    // src/main/resources/ModelDef.g:26:1: bottomup : ( exitClass | exitInterface | exitMethod );
    public final void bottomup() throws RecognitionException {
        try {
            // src/main/resources/ModelDef.g:27:5: ( exitClass | exitInterface | exitMethod )
            int alt2=3;
            switch ( input.LA(1) ) {
            case 28:
                {
                alt2=1;
                }
                break;
            case 32:
                {
                alt2=2;
                }
                break;
            case METHOD_DECL:
                {
                alt2=3;
                }
                break;
            default:
                if (state.backtracking>0) {state.failed=true; return ;}
                NoViableAltException nvae =
                    new NoViableAltException("", 2, 0, input);

                throw nvae;

            }

            switch (alt2) {
                case 1 :
                    // src/main/resources/ModelDef.g:27:7: exitClass
                    {
                    pushFollow(FOLLOW_exitClass_in_bottomup105);
                    exitClass();

                    state._fsp--;
                    if (state.failed) return ;

                    }
                    break;
                case 2 :
                    // src/main/resources/ModelDef.g:28:7: exitInterface
                    {
                    pushFollow(FOLLOW_exitInterface_in_bottomup113);
                    exitInterface();

                    state._fsp--;
                    if (state.failed) return ;

                    }
                    break;
                case 3 :
                    // src/main/resources/ModelDef.g:29:7: exitMethod
                    {
                    pushFollow(FOLLOW_exitMethod_in_bottomup121);
                    exitMethod();

                    state._fsp--;
                    if (state.failed) return ;

                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "bottomup"



    // $ANTLR start "enterClass"
    // src/main/resources/ModelDef.g:32:1: enterClass : ^( 'class' name= IDENTIFIER ( ^( 'implements' sup= . ) )? . ) ;
    public final void enterClass() throws RecognitionException {
        ModelAST name=null;
        ModelAST sup=null;

        try {
            // src/main/resources/ModelDef.g:33:5: ( ^( 'class' name= IDENTIFIER ( ^( 'implements' sup= . ) )? . ) )
            // src/main/resources/ModelDef.g:33:10: ^( 'class' name= IDENTIFIER ( ^( 'implements' sup= . ) )? . )
            {
            match(input,28,FOLLOW_28_in_enterClass142); if (state.failed) return ;

            match(input, Token.DOWN, null); if (state.failed) return ;
            name=(ModelAST)match(input,IDENTIFIER,FOLLOW_IDENTIFIER_in_enterClass146); if (state.failed) return ;

            // src/main/resources/ModelDef.g:33:36: ( ^( 'implements' sup= . ) )?
            int alt3=2;
            int LA3_0 = input.LA(1);

            if ( (LA3_0==30) ) {
                int LA3_1 = input.LA(2);

                if ( (LA3_1==DOWN) ) {
                    int LA3_3 = input.LA(3);

                    if ( ((LA3_3 >= CLSS_DECL && LA3_3 <= 38)) ) {
                        int LA3_4 = input.LA(4);

                        if ( (LA3_4==DOWN) ) {
                            alt3=1;
                        }
                        else if ( (LA3_4==UP) ) {
                            int LA3_6 = input.LA(5);

                            if ( ((LA3_6 >= CLSS_DECL && LA3_6 <= 38)) ) {
                                alt3=1;
                            }
                        }
                    }
                }
            }
            switch (alt3) {
                case 1 :
                    // src/main/resources/ModelDef.g:33:37: ^( 'implements' sup= . )
                    {
                    match(input,30,FOLLOW_30_in_enterClass150); if (state.failed) return ;

                    match(input, Token.DOWN, null); if (state.failed) return ;
                    sup=(ModelAST)input.LT(1);

                    matchAny(input); if (state.failed) return ;

                    match(input, Token.UP, null); if (state.failed) return ;


                    }
                    break;

            }


            matchAny(input); if (state.failed) return ;

            match(input, Token.UP, null); if (state.failed) return ;


            if ( state.backtracking==1 ) { // def class but leave superclass blank until ref phase
                    System.out.println("line "+name.getLine()+
                                       ": def class "+(name!=null?name.getText():null));
                    // record scope in AST for next pass
                    if ( sup!=null ) sup.scope = currentScope; 
                    ClassSymbol cs = new ClassSymbol((name!=null?name.getText():null),currentScope,null,"class");
                    cs.def = name;           // point from symbol table into AST
                    name.symbol = cs;        // point from AST into symbol table
                    currentScope.define(cs);  // def class in current scope
                    currentScope = cs;        // set current scope to class scope
                    }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "enterClass"



    // $ANTLR start "exitClass"
    // src/main/resources/ModelDef.g:47:1: exitClass : 'class' ;
    public final void exitClass() throws RecognitionException {
        try {
            // src/main/resources/ModelDef.g:48:5: ( 'class' )
            // src/main/resources/ModelDef.g:48:9: 'class'
            {
            match(input,28,FOLLOW_28_in_exitClass189); if (state.failed) return ;

            if ( state.backtracking==1 ) {
                    System.out.println("members: "+currentScope);
                    currentScope = currentScope.getEnclosingScope();    // pop scope
                    }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "exitClass"



    // $ANTLR start "enterInterface"
    // src/main/resources/ModelDef.g:55:1: enterInterface : ^( 'interface' name= IDENTIFIER ( ^( 'extends' sup= . ) )? . ) ;
    public final void enterInterface() throws RecognitionException {
        ModelAST name=null;
        ModelAST sup=null;

        try {
            // src/main/resources/ModelDef.g:56:5: ( ^( 'interface' name= IDENTIFIER ( ^( 'extends' sup= . ) )? . ) )
            // src/main/resources/ModelDef.g:56:10: ^( 'interface' name= IDENTIFIER ( ^( 'extends' sup= . ) )? . )
            {
            match(input,32,FOLLOW_32_in_enterInterface220); if (state.failed) return ;

            match(input, Token.DOWN, null); if (state.failed) return ;
            name=(ModelAST)match(input,IDENTIFIER,FOLLOW_IDENTIFIER_in_enterInterface224); if (state.failed) return ;

            // src/main/resources/ModelDef.g:56:40: ( ^( 'extends' sup= . ) )?
            int alt4=2;
            int LA4_0 = input.LA(1);

            if ( (LA4_0==29) ) {
                int LA4_1 = input.LA(2);

                if ( (LA4_1==DOWN) ) {
                    int LA4_3 = input.LA(3);

                    if ( ((LA4_3 >= CLSS_DECL && LA4_3 <= 38)) ) {
                        int LA4_4 = input.LA(4);

                        if ( (LA4_4==DOWN) ) {
                            alt4=1;
                        }
                        else if ( (LA4_4==UP) ) {
                            int LA4_6 = input.LA(5);

                            if ( ((LA4_6 >= CLSS_DECL && LA4_6 <= 38)) ) {
                                alt4=1;
                            }
                        }
                    }
                }
            }
            switch (alt4) {
                case 1 :
                    // src/main/resources/ModelDef.g:56:41: ^( 'extends' sup= . )
                    {
                    match(input,29,FOLLOW_29_in_enterInterface228); if (state.failed) return ;

                    match(input, Token.DOWN, null); if (state.failed) return ;
                    sup=(ModelAST)input.LT(1);

                    matchAny(input); if (state.failed) return ;

                    match(input, Token.UP, null); if (state.failed) return ;


                    }
                    break;

            }


            matchAny(input); if (state.failed) return ;

            match(input, Token.UP, null); if (state.failed) return ;


            if ( state.backtracking==1 ) { // def class but leave superclass blank until ref phase
                    System.out.println("line "+name.getLine()+
                                       ": def interface "+(name!=null?name.getText():null));
                    // record scope in AST for next pass
                    if ( sup!=null ) sup.scope = currentScope; 
                    ClassSymbol cs = new ClassSymbol((name!=null?name.getText():null),currentScope,null,"interface");
                    cs.def = name;           // point from symbol table into AST
                    name.symbol = cs;        // point from AST into symbol table
                    currentScope.define(cs);  // def class in current scope
                    currentScope = cs;        // set current scope to class scope
                    }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "enterInterface"



    // $ANTLR start "exitInterface"
    // src/main/resources/ModelDef.g:70:1: exitInterface : 'interface' ;
    public final void exitInterface() throws RecognitionException {
        try {
            // src/main/resources/ModelDef.g:71:5: ( 'interface' )
            // src/main/resources/ModelDef.g:71:9: 'interface'
            {
            match(input,32,FOLLOW_32_in_exitInterface267); if (state.failed) return ;

            if ( state.backtracking==1 ) {
                    System.out.println("members: "+currentScope);
                    currentScope = currentScope.getEnclosingScope();    // pop scope
                    }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "exitInterface"



    // $ANTLR start "methodDeclaration"
    // src/main/resources/ModelDef.g:78:1: methodDeclaration : ^( METHOD_DECL type ID= IDENTIFIER ) ;
    public final void methodDeclaration() throws RecognitionException {
        ModelAST ID=null;
        ModelAST type1 =null;


        try {
            // src/main/resources/ModelDef.g:79:5: ( ^( METHOD_DECL type ID= IDENTIFIER ) )
            // src/main/resources/ModelDef.g:79:9: ^( METHOD_DECL type ID= IDENTIFIER )
            {
            match(input,METHOD_DECL,FOLLOW_METHOD_DECL_in_methodDeclaration301); if (state.failed) return ;

            match(input, Token.DOWN, null); if (state.failed) return ;
            pushFollow(FOLLOW_type_in_methodDeclaration303);
            type1=type();

            state._fsp--;
            if (state.failed) return ;

            ID=(ModelAST)match(input,IDENTIFIER,FOLLOW_IDENTIFIER_in_methodDeclaration307); if (state.failed) return ;

            match(input, Token.UP, null); if (state.failed) return ;


            if ( state.backtracking==1 ) {
                    System.out.println("line "+ID.getLine()+": def method "+(ID!=null?ID.getText():null));
                    type1.scope = currentScope;
                    MethodSymbol ms = new MethodSymbol((ID!=null?ID.getText():null),null,currentScope);
                    ms.def = ID;            // track AST location of def's ID
                    ID.symbol = ms;         // track in AST
                    currentScope.define(ms); // def method in globals
                    currentScope = ms;       // set current scope to method scope
                    }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "methodDeclaration"



    // $ANTLR start "exitMethod"
    // src/main/resources/ModelDef.g:91:1: exitMethod : METHOD_DECL ;
    public final void exitMethod() throws RecognitionException {
        try {
            // src/main/resources/ModelDef.g:92:5: ( METHOD_DECL )
            // src/main/resources/ModelDef.g:92:9: METHOD_DECL
            {
            match(input,METHOD_DECL,FOLLOW_METHOD_DECL_in_exitMethod337); if (state.failed) return ;

            if ( state.backtracking==1 ) {
                    System.out.println("args: "+currentScope);
                    currentScope = currentScope.getEnclosingScope();    // pop arg scope
                    }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "exitMethod"



    // $ANTLR start "fieldDeclaration"
    // src/main/resources/ModelDef.g:99:1: fieldDeclaration : ^( FIELD_DECL type ID= IDENTIFIER ) ;
    public final void fieldDeclaration() throws RecognitionException {
        ModelAST ID=null;
        ModelAST type2 =null;


        try {
            // src/main/resources/ModelDef.g:100:5: ( ^( FIELD_DECL type ID= IDENTIFIER ) )
            // src/main/resources/ModelDef.g:100:9: ^( FIELD_DECL type ID= IDENTIFIER )
            {
            match(input,FIELD_DECL,FOLLOW_FIELD_DECL_in_fieldDeclaration368); if (state.failed) return ;

            match(input, Token.DOWN, null); if (state.failed) return ;
            pushFollow(FOLLOW_type_in_fieldDeclaration370);
            type2=type();

            state._fsp--;
            if (state.failed) return ;

            ID=(ModelAST)match(input,IDENTIFIER,FOLLOW_IDENTIFIER_in_fieldDeclaration374); if (state.failed) return ;

            match(input, Token.UP, null); if (state.failed) return ;


            if ( state.backtracking==1 ) {
                    System.out.println("line "+ID.getLine()+": def "+type2+" field "+(ID!=null?ID.getText():null));
                    type2.scope = currentScope;
                    VariableSymbol vs = new VariableSymbol((ID!=null?ID.getText():null),null);
                    vs.def = ID;            // track AST location of def's ID
                    ID.symbol = vs;         // track in AST
                    currentScope.define(vs);
                    }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return ;
    }
    // $ANTLR end "fieldDeclaration"



    // $ANTLR start "type"
    // src/main/resources/ModelDef.g:111:1: type returns [ModelAST tsym] : ^( ( REL_DECL | TYPE_DECL ) ID= IDENTIFIER ) ;
    public final ModelAST type() throws RecognitionException {
        ModelAST tsym = null;


        ModelAST ID=null;

        try {
            // src/main/resources/ModelDef.g:112:5: ( ^( ( REL_DECL | TYPE_DECL ) ID= IDENTIFIER ) )
            // src/main/resources/ModelDef.g:112:9: ^( ( REL_DECL | TYPE_DECL ) ID= IDENTIFIER )
            {
            if ( (input.LA(1) >= REL_DECL && input.LA(1) <= TYPE_DECL) ) {
                input.consume();
                state.errorRecovery=false;
                state.failed=false;
            }
            else {
                if (state.backtracking>0) {state.failed=true; return tsym;}
                MismatchedSetException mse = new MismatchedSetException(null,input);
                throw mse;
            }


            match(input, Token.DOWN, null); if (state.failed) return tsym;
            ID=(ModelAST)match(input,IDENTIFIER,FOLLOW_IDENTIFIER_in_type417); if (state.failed) return tsym;

            match(input, Token.UP, null); if (state.failed) return tsym;


            if ( state.backtracking==1 ) {
            	    // get scope from AST; use to resolve type name and save it in AST
            	    tsym = ID; // return Type from this rule
            		}

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }

        finally {
        	// do for sure before leaving
        }
        return tsym;
    }
    // $ANTLR end "type"

    // Delegated rules


 

    public static final BitSet FOLLOW_enterClass_in_topdown60 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_enterInterface_in_topdown68 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_fieldDeclaration_in_topdown78 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_methodDeclaration_in_topdown88 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_exitClass_in_bottomup105 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_exitInterface_in_bottomup113 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_exitMethod_in_bottomup121 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_28_in_enterClass142 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_IDENTIFIER_in_enterClass146 = new BitSet(new long[]{0x0000007FFFFFFFF0L});
    public static final BitSet FOLLOW_30_in_enterClass150 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_28_in_exitClass189 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_32_in_enterInterface220 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_IDENTIFIER_in_enterInterface224 = new BitSet(new long[]{0x0000007FFFFFFFF0L});
    public static final BitSet FOLLOW_29_in_enterInterface228 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_32_in_exitInterface267 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_METHOD_DECL_in_methodDeclaration301 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_type_in_methodDeclaration303 = new BitSet(new long[]{0x0000000000000080L});
    public static final BitSet FOLLOW_IDENTIFIER_in_methodDeclaration307 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_METHOD_DECL_in_exitMethod337 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_FIELD_DECL_in_fieldDeclaration368 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_type_in_fieldDeclaration370 = new BitSet(new long[]{0x0000000000000080L});
    public static final BitSet FOLLOW_IDENTIFIER_in_fieldDeclaration374 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_set_in_type409 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_IDENTIFIER_in_type417 = new BitSet(new long[]{0x0000000000000008L});

}